package com.lanxum.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lanxum.common.constant.Constant;
import com.lanxum.common.controller.Base;
import com.lanxum.common.entity.BarcodeParam;
import com.lanxum.common.enums.CommonEnum;
import com.lanxum.common.task.BarcodeTask;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author li.sun
 * @Description:
 * @date 2020/10/17 17:42
 */
public class BarcodeUtil extends Base {

    private static final Logger logger = LoggerFactory.getLogger(BarcodeUtil.class);

    private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100,500,100L,TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2000));

//    public static void main(String[] args) {
//        String barcodeData = "{\n" +
//                "\n" +
//                "\t\"copies\": \"2\",\n" +
//                "\t\"pages\": \"2\",\n" +
//                "\t\"fileName\": \"2121.pdf\",\n" +
//                "\t\"pdfData\": {\n" +
//                "\t\t\"filePath\": \"PDF文件路径－必填\",\n" +
//                "\t\t\"paperSize\": \"纸型－必填；例：A4\",\n" +
//                "\t\t\"outPdfFilePath\": \"嵌入条码后的PDF文件路径－必填\",\n" +
//                "\t\t\"duplex\": \"单/双面－非必填；0：单面（默认），1：双面\",\n" +
//                "\t\t\"imagePosition\": \"条码和条码文件信息位置-非必填；bottom-right：右下角（默认），bottom：底部居中，bottom-left：左下角，top-right：右上角，top：顶部居中，top-left：左上角\",\n" +
//                "\t\t\"orientation\": \"文件横/纵项－非必填；0：纵项（默认），1：横项\",\n" +
//                "\t\t\"shiftAdjustmentX\": \"非必填；20：默认\",\n" +
//                "\t\t\"shiftAdjustmentY\": \"非必填；20：默认\",\n" +
//                "\t\t\"width\": \"宽－非必填；150：默认\",\n" +
//                "\t\t\"height\": \"高－非必填；30：默认\"\n" +
//                "\t},\n" +
//                "\t\"barcodeData\": {\n" +
//                "\t\t\"outBarcodePngPath\": \"D:/opt/DYSJ/printJava/barcode/png\",\n" +
//                "\t\t\"imageContent\": \"D-密级-用户名称-部门名称-20201017222740\",\n" +
//                "\t\t\"textContent\": \"D-密级-用户名称-部门名称-20201017222740\",\n" +
//                "\t\t\"textFontSize\": \"20\",\n" +
//                "\t\t\"barcodeType\": \"0\",\n" +
//                "\t\t\"scaling\": \"4\"\n" +
//                "\t}\n" +
//                "}";
//        String barcodeStr = new BarcodeUtil().createBarcodeImg(barcodeData);
//        System.out.println(barcodeStr);
//    }

    /**
     *  新生成条码图片
     * @param barcodeData
     * @return
     */
    public static String createBarcodeImg(String barcodeData) {

        // key:二维码图片名称，value:二维码图片路径+二维码图片名称的全路径
        JSONObject barcodeResutlJSON = new JSONObject();
        try {
            // 参数验证
            String validateResult = validateBarcodeParam(barcodeData);
            if (StringUtils.isNotBlank(validateResult))
                return validateResult;

            JSONObject rootJson = JSON.parseObject(barcodeData);
            JSONObject jsonObject = rootJson.getJSONObject("barcodeData");
            // 份
            String copies = rootJson.getString("copies");
            // 页
            String pages = rootJson.getString("pages");
            // 文件名称
            String fileName = rootJson.getString("fileName");
            // 二维码文件生成路径
            String outBarcodePngPath = jsonObject.getString("outBarcodePngPath");
            // 条码信息
            String imageContent = jsonObject.getString("imageContent");
            // 条码文本信息
            String textContent = jsonObject.getString("textContent");
            // 条码文本字体大小
            String textFontSize;
            if (jsonObject.containsKey("textFontSize"))
                textFontSize = jsonObject.getString("textFontSize");
            else
                textFontSize = "15";
            // 条码生成类型，0：条码和条码文件信息都生成（默认），1：只生成条码信息，2：只生成条码文本信息
            String barcodeType;
            if (jsonObject.containsKey("barcodeType"))
                barcodeType = jsonObject.getString("barcodeType");
            else
                barcodeType = "0";
            // 条码大小比例，4：默认
            String scaling;
            if (jsonObject.containsKey("scaling"))
                scaling = jsonObject.getString("scaling");
            else
                scaling = "2";

            // 生成条码文件路径
            File pngDir = new File(outBarcodePngPath);
            if (!pngDir.exists())
                pngDir.mkdirs();

            // 生成二维码图片
            for (int i = 1; i < Integer.parseInt(copies) + 1; i++) {
                String copiesNumber = CommonUtil.handleCopiesPages(copies, i);
                StringBuffer imageContentCopies = new StringBuffer();
                imageContentCopies.append(imageContent).append("-").append(copiesNumber);

                StringBuffer textContentCopies = new StringBuffer();
                textContentCopies.append(textContent).append("-").append(copiesNumber);

                for (int j = 1; j < Integer.parseInt(pages) + 1; j++) {
                    String pagesNumber = CommonUtil.handleCopiesPages(pages, j);
                    StringBuffer imageContentPage = new StringBuffer();
                    imageContentPage.append(imageContentCopies).append("-").append(pagesNumber);
                    StringBuffer textContentPage = new StringBuffer();
                    textContentPage.append(textContentCopies).append("-").append(pagesNumber);
                    BarcodeParam bp = new BarcodeParam();
                    // 条码图片路径
                    bp.setImagePath(outBarcodePngPath + File.separator);
                    // 文件名称_份数_页数.png
//                barcodePngName = UUID.randomUUID() + "_" + copiesNumber + "_" + pagesNumber + ".png";
                    String barcodePngName = fileName + "_" + copiesNumber + "_" + pagesNumber + ".png";
                    bp.setImageName(barcodePngName);
                    if (StringUtils.isNotBlank(textFontSize))
                        bp.setTextFontSize(Integer.parseInt(textFontSize));
                    bp.setScaling(Integer.parseInt(scaling));
                    if (StringUtils.isBlank(barcodeType) || StringUtils.equals(barcodeType, "0")) {
                        bp.setImageContent(imageContentPage.toString());
                        bp.setTextContent(textContentPage.toString());
                    } else if (StringUtils.equals(barcodeType, "1")) {
                        bp.setImageContent(imageContentPage.toString());
                    } else if (StringUtils.equals(barcodeType, "2")) {
                        bp.setImageContent(textContentPage.toString());
                    }
                    Future future = threadPoolExecutor.submit(new BarcodeTask(bp));
                    if (future != null) {
                        String imageDataResult = (String) future.get();
                        barcodeResutlJSON.put(barcodePngName, imageDataResult);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("生成二维码异常－Exception:{}", e);
            return respJson(CommonEnum.ERROR);
        }
        logger.info("新生成二维码图片－－－完成");
        return respJson(CommonEnum.SUCCESS.getCode(), CommonEnum.SUCCESS.getMessage(), barcodeResutlJSON);
    }

    private static String validateBarcodeParam(String barcodeData) {
        if (StringUtils.isBlank(barcodeData)) {
            return respJson(CommonEnum.PARAM_NULL_ERROR);
        }
        JSONObject rootJson = null;
        JSONObject jsonObject = null;
        try {
            rootJson = JSONObject.parseObject(barcodeData);
            if (null == rootJson ){
                return respJson(CommonEnum.PARAM_ERROR, Constant.CREATE_BARCODE_EXAMPLE);
            }
            if (!rootJson.containsKey("barcodeData")) {
                return respJson(CommonEnum.PARAM_NULL_ERROR, "barcodeData:二维码数据不存在");
            }
            jsonObject = rootJson.getJSONObject("barcodeData");
        } catch (Exception e) {
            return respJson(CommonEnum.PARAM_ERROR, Constant.CREATE_BARCODE_EXAMPLE);
        }

        if (!rootJson.containsKey("copies") || StringUtils.isBlank(rootJson.getString("copies"))) {
            return respJson(CommonEnum.PARAM_NULL_ERROR, "copies:份数, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
        }

        if (!rootJson.containsKey("pages") || StringUtils.isBlank(rootJson.getString("pages"))) {
            return respJson(CommonEnum.PARAM_NULL_ERROR, "pages:页数, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
        }

        if (!rootJson.containsKey("fileName") || StringUtils.isBlank(rootJson.getString("fileName"))) {
            return respJson(CommonEnum.PARAM_NULL_ERROR, "fileName:文件名称, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
        }

        if (!jsonObject.containsKey("outBarcodePngPath") || StringUtils.isBlank(jsonObject.getString("outBarcodePngPath"))) {
            return respJson(CommonEnum.PARAM_NULL_ERROR, "outBarcodePngPath:生成条码文件路径, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
        }

//        if (!jsonObject.containsKey("safeLevel") || StringUtils.isBlank(jsonObject.getString("safeLevel"))) {
//            return respJson(CommonEnum.PARAM_NULL_ERROR, "safeLevel:密级, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
//        }

        if (!jsonObject.containsKey("imageContent") || StringUtils.isBlank(jsonObject.getString("imageContent"))) {
            return respJson(CommonEnum.PARAM_NULL_ERROR, "imageContent:条码信息, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
        }

        if (!jsonObject.containsKey("textContent") || StringUtils.isBlank(jsonObject.getString("textContent"))) {
            return respJson(CommonEnum.PARAM_NULL_ERROR, "textContent:条码文本信息, " + CommonEnum.PARAM_NULL_ERROR.getMessage());
        }

        return null;
    }



}
